package com.xiao.controller;


import com.xiao.domain.ResponseResult;
import com.xiao.enums.AppHttpCodeEnum;
import com.xiao.exception.SystemException;
import com.xiao.domain.pojo.BlogSysUser;
import com.xiao.domain.pojo.LoginUser;
import com.xiao.domain.pojo.SysMenu;
import com.xiao.service.AdminLoginService;
import com.xiao.service.SysMenuService;
import com.xiao.service.SysRoleService;
import com.xiao.utils.BeanCopyUtils;
import com.xiao.utils.SecurityUtils;
import com.xiao.domain.vo.AdminUserInfoVo;
import com.xiao.domain.vo.RoutersVo;
import com.xiao.domain.vo.UserInfoVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@Api(tags = "博客后台登录与注销")
public class AdminLoginController {
    @Autowired
    AdminLoginService adminLoginService;

    // 登录请求
    @PostMapping("/user/login")
    @ApiOperation("用户登录请求")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "blogSysUser",value = "用户实体类")
    })
    public ResponseResult login(@RequestBody BlogSysUser blogSysUser){ // 前端传递来的参数用 实体类来接

/*        // ----------- 原始写法 Start -----------
       //如果字符序列不为null值,并且字符序列的长度大于0,并且不含有空白字符序列,则返回true
        if (!StringUtils.hasText(blogSysUser.getUserName())){// 使用 springframework 包下
             // 提示 必须要传入用户名
            throw new RuntimeException("必须填写用户名");
        }
        // ----------- 原始写法 End -----------*/


        // ----------- 通常写法 Start -----------
        if (!StringUtils.hasText(blogSysUser.getUserName())){
            // 提示 必须要传入用户名
            throw new SystemException(AppHttpCodeEnum.USERNAME_NOT_NULL);
        }
        // ----------- 通常写法 End -----------


        ResponseResult responseResult = adminLoginService.login(blogSysUser);
        return responseResult;
    }

    @Autowired
    private SysMenuService sysMenuService;
    @Autowired
    private SysRoleService sysRoleService;

    @GetMapping("/getInfo") // "getInfo"
    @ApiOperation("获取登录用户的 权限信息，和角色关键字")
    public ResponseResult<AdminUserInfoVo> getInfo(){
        // 1. 获取当前登录的用户
        LoginUser loginUser = SecurityUtils.getLoginUser();
        // 2. 根据用户 ID 查询权限信息
        Long userId = loginUser.getBlogSysUser().getId();

        List<String> perms =  sysMenuService.selectPermsByUserId(userId);
      // 3. 根据用户ID查询角色关键字
        List<String> rolekeyList = sysRoleService.selectRolekeyByUserId(userId);

        // 4. 获取用户信息 包装成 VO
        BlogSysUser blogSysUser = loginUser.getBlogSysUser();

        UserInfoVo userInfoVo = BeanCopyUtils.copyBean(blogSysUser, UserInfoVo.class);

        // 5. 统一响应
        AdminUserInfoVo adminUserInfoVo = new AdminUserInfoVo(perms, rolekeyList, userInfoVo);

        return ResponseResult.okResult(adminUserInfoVo);

    }

    @GetMapping("/getRouters")
    @ApiOperation("获取路由信息，即该用户，可以访问那些菜单")
    public ResponseResult<RoutersVo> getRouters(){
        // 1. 获取当前登入用户
        Long userId = SecurityUtils.getUserId();
        // 2. 查询 Sys_menu 结果是树的形式
        List<SysMenu> sysMenus = sysMenuService.selectRouterMenuTreeByUserId(userId);
        // 3. 封装数据返回
        RoutersVo routersVo = new RoutersVo(sysMenus);

        return ResponseResult.okResult(routersVo);

    }

    @PostMapping("/user/logout")
    @ApiOperation("注销登录,清除 Redis 用户信息")
    public  ResponseResult logout(){
        ResponseResult result = adminLoginService.logout();
        return result;
    }



}